package com.bluestar.tools.common.adapter;

import android.graphics.Bitmap;
import android.text.SpannableStringBuilder;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RatingBar;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.bluestar.tools.R;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public class BaseRecycleView {

    public abstract static class Adapter extends RecyclerView.Adapter<ViewHolder> {

        protected final String TAG = this.getClass().getSimpleName();

        // 用来存放底部和头部View的集合  比Map要高效一些
        // 可以点击进入看一下官方的解释
        /**
         * SparseArrays map integers to Objects.  Unlike a normal array of Objects,
         * there can be gaps in the indices.  It is intended to be more memory efficient
         * than using a HashMap to map Integers to Objects, both because it avoids
         * auto-boxing keys and its data structure doesn't rely on an extra entry object
         * for each mapping.
         */
        private SparseArray<View> mHeaderViews;
        private SparseArray<View> mFooterViews;

        // 基本的头部类型开始位置  用于viewType
        private static int BASE_ITEM_TYPE_HEADER = 10000000;
        // 基本的底部类型开始位置  用于viewType
        private static int BASE_ITEM_TYPE_FOOTER = 20000000;

        private List<ItemData> mData;

        public Adapter() {
            mData = new ArrayList<>();
            mHeaderViews = new SparseArray<>();
            mFooterViews = new SparseArray<>();
        }

        public <T> Adapter(List<T> data, int viewType) {
            mData = new ArrayList<>();
            for (T bean : data) {
                ItemData<T> itemData = new ItemData<>(bean, viewType);
                mData.add(itemData);
            }
            //mData.addAll(data);
            mHeaderViews = new SparseArray<>();
            mFooterViews = new SparseArray<>();
        }

        public <T> Adapter(T[] data, int viewType) {
            this.mData = new ArrayList<>();
            for (T bean : data) {
                ItemData<T> itemData = new ItemData<>(bean, viewType);
                mData.add(itemData);
            }
            //Collections.addAll(this.mData, data);
            mHeaderViews = new SparseArray<>();
            mFooterViews = new SparseArray<>();
        }

        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

            // viewType 可能就是 SparseArray 的 key
            if (isHeaderViewType(viewType)) {
                View headerView = mHeaderViews.get(viewType);
                return createHeaderFooterViewHolder(headerView);
            }

            if (isFooterViewType(viewType)) {
                View footerView = mFooterViews.get(viewType);
                return createHeaderFooterViewHolder(footerView);
            }

            if (viewType == ViewType.DEFAULT_LIST.ordinal()) {
                return getViewHolder(parent, R.layout.item_main);

            } else {
                return null;
            }
        }

        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            if (isHeaderPosition(position) || isFooterPosition(position)) {
                return;
            }
            // 计算一下位置
            position = position - mHeaderViews.size();

            convert(holder, getItem(position), position);
        }

        @Override
        public int getItemCount() {
            return getDataSize() + mHeaderViews.size() + mFooterViews.size();
        }

        private int getDataSize() {
            if (mData != null) {
                return mData.size();
            }
            return 0;
        }

        public ItemData getItem(int position) {
            if (mData.size() > position)
                return mData.get(position);
            return null;
        }

        @Override
        public int getItemViewType(int position) {
            if (isHeaderPosition(position)) {
                // 直接返回position位置的key
                return mHeaderViews.keyAt(position);
            }
            if (isFooterPosition(position)) {
                // 直接返回position位置的key
                position = position - mHeaderViews.size() - getDataSize();
                return mFooterViews.keyAt(position);
            }
            // 返回列表Adapter的getItemViewType
            position = position - mHeaderViews.size();

            return mData.get(position).getDataType();
        }

        public abstract void convert(ViewHolder holder, ItemData item, int position);

        public <T> void setData(List<T> data, int viewType) {
            if (data == null || data.size() == 0) {
                if (mData != null) {
                    // 假如传入的 data 是空的，把 mData 清空
                    mData.clear();
                }

            } else {
                mData.clear();
                for (T bean : data) {
                    ItemData<T> itemData = new ItemData<>(bean, viewType);
                    mData.add(itemData);
                }
                //mData.addAll(data);
            }
            notifyDataSetChanged();
        }

        private ViewHolder getViewHolder(ViewGroup parent, int layoutId) {
            return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false));
        }

        /**
         * 是不是底部类型
         */
        private boolean isFooterViewType(int viewType) {
            int position = mFooterViews.indexOfKey(viewType);
            return position >= 0;
        }

        /**
         * 创建头部或者底部的ViewHolder
         */
        private ViewHolder createHeaderFooterViewHolder(View view) {
            return new ViewHolder(view) {

            };
        }

        /**
         * 是不是头部类型
         */
        private boolean isHeaderViewType(int viewType) {
            int position = mHeaderViews.indexOfKey(viewType);
            return position >= 0;
        }

        /**
         * 是不是底部位置
         */
        private boolean isFooterPosition(int position) {
            return position >= (mHeaderViews.size() + getDataSize());
        }

        /**
         * 是不是头部位置
         */
        private boolean isHeaderPosition(int position) {
            return position < mHeaderViews.size();
        }

        // 添加头部
        public void addHeaderView(View view) {
            int position = mHeaderViews.indexOfValue(view);
            if (position < 0) {
                mHeaderViews.put(BASE_ITEM_TYPE_HEADER++, view);
            }
            notifyDataSetChanged();
        }

        // 添加底部
        public void addFooterView(View view) {
            int position = mFooterViews.indexOfValue(view);
            if (position < 0) {
                mFooterViews.put(BASE_ITEM_TYPE_FOOTER++, view);
            }
            notifyDataSetChanged();
        }

        // 移除头部
        public void removeHeaderView(View view) {
            int index = mHeaderViews.indexOfValue(view);
            if (index < 0)
                return;
            mHeaderViews.removeAt(index);
            notifyDataSetChanged();
        }

        // 移除底部
        public void removeFooterView(View view) {
            int index = mFooterViews.indexOfValue(view);
            if (index < 0)
                return;
            mFooterViews.removeAt(index);
            notifyDataSetChanged();
        }

        /**
         * 解决GridLayoutManager添加头部和底部不占用一行的问题
         * @param recycler
         * @version 1.0
         */
        public void adjustSpanSize(RecyclerView recycler) {
            if (recycler.getLayoutManager() instanceof GridLayoutManager) {
                final GridLayoutManager layoutManager = (GridLayoutManager) recycler.getLayoutManager();
                layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                    @Override
                    public int getSpanSize(int position) {
                        boolean isHeaderOrFooter =
                            isHeaderPosition(position) || isFooterPosition(position);
                        return isHeaderOrFooter ? layoutManager.getSpanCount() : 1;
                    }
                });
            }
        }
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private final SparseArray<View> mViews;

        private View mConvertView;

        public ViewHolder(View convertView) {
            super(convertView);
            this.mViews = new SparseArray<>();
            //mConvertView = LayoutInflater.from(context).inflate(resLayoutId, parent, false);
            mConvertView = convertView;
        }

        public <T extends View> T getView(int viewId) {
            return retrieveView(viewId);
        }

        @SuppressWarnings("unchecked")
        private <T extends View> T retrieveView(int viewId) {
            View view = mViews.get(viewId);
            if (view == null) {
                view = mConvertView.findViewById(viewId);
                mViews.put(viewId, view);
            }
            return (T) view;
        }

        public View getConvertView() {
            return mConvertView;
        }

        public ViewHolder setText(int viewId, String text) {
            TextView tv = getView(viewId);
            tv.setText(text);
            return this;
        }

        public ViewHolder setText(int viewId, SpannableStringBuilder style) {
            TextView tv = getView(viewId);
            tv.setText(style);
            return this;
        }

        public ViewHolder setTextColor(int viewId, int color) {
            TextView tv = getView(viewId);
            tv.setTextColor(color);
            return this;
        }

        //    public ViewHolder setImageResource(int viewId, int drawableId) {
        //        Glide.with(context)
        //                .load(drawableId)
        //                .centerCrop()
        //                .into((ImageView) retrieveView(viewId));
        //        return this;
        //    }

        //    public ViewHolder setImageBitmap(int viewId, Bitmap bm) {
        //        byte[] bitmapBytes = bitmapToByte(bm);
        //
        //        Glide.with(context)
        //                .load(bitmapBytes)
        //                .centerCrop()
        //                .into((ImageView) retrieveView(viewId));
        //        return this;
        //    }

        private byte[] bitmapToByte(Bitmap bm) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            bm.compress(Bitmap.CompressFormat.PNG, 100, out);
            return out.toByteArray();
        }

        //    public ViewHolder setImageByUrl(int viewId, String url) {
        //        return setImageByUrl(viewId, url, -1);
        //    }

        public ViewHolder setImageByUrl(int viewId, String url, int defaultImageRes) {
            RequestOptions requestOptions = new RequestOptions()
                .placeholder(defaultImageRes);
            Glide.with(mConvertView.getContext())
                .load(url)
                .apply(requestOptions)
                .into((ImageView) retrieveView(viewId));
            return this;
        }

        public ViewHolder setImageBitmap(int viewId, Bitmap bitmap, int defaultImageRes) {
            RequestOptions requestOptions = new RequestOptions()
                .placeholder(defaultImageRes);
            Glide.with(mConvertView.getContext())
                .load(bitmap)
                .apply(requestOptions)
                .into((ImageView) retrieveView(viewId));
            return this;
        }

        public ViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
            View view = retrieveView(viewId);
            view.setOnClickListener(listener);
            return this;
        }

        public ViewHolder setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
            View view = retrieveView(viewId);
            view.setOnLongClickListener(listener);
            return this;
        }

        public ViewHolder setTextBackground(int viewId, int color) {
            TextView tv = getView(viewId);
            tv.setBackgroundColor(color);
            return this;
        }

        public ViewHolder setRadioButtonText(int viewId, String text) {
            RadioButton radioButton = getView(viewId);
            radioButton.setText(text);
            return this;
        }

        public ViewHolder setRadioButtonChecked(int viewId, boolean checked) {
            RadioButton radioButton = getView(viewId);
            radioButton.setChecked(checked);
            return this;
        }

        public ViewHolder setVisible(int viewId, int visible) {
            View view = getView(viewId);
            view.setVisibility(visible);
            return this;
        }

        public ViewHolder setRating(int viewId, float ratingValue) {
            RatingBar view = getView(viewId);
            view.setRating(ratingValue);
            return this;
        }
    }

    /**
     * @author : lifei
     * 创建时间： 19-10-10
     * 更改时间： 19-10-10
     * Email : allen.lee723@qq.com
     * @version :
     * Description：RecyclerView 数据
     */
    public static class ItemData<T> {

        // 用来装载不同类型的 item 数据 bean
        private T data;
        // item 数据 bean 的类型
        private int dataType;

        public ItemData() {
        }

        public ItemData(T data, int dataType) {
            this.data = data;
            this.dataType = dataType;
        }

        public T getData() {
            return data;
        }

        public void setData(T data) {
            this.data = data;
        }

        public int getDataType() {
            return dataType;
        }

        public void setDataType(int dataType) {
            this.dataType = dataType;
        }
    }

    public enum ViewType {
        DEFAULT_LIST, // 默认列表
    }
}